/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.perlak.filesearch;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;


/**
 *
 * @author Mateusz
 */
public class SingleFileResult {
    public static final int FULL_FILE_LEVEL = 0;
    public static final int NORMAL_FILE_LEVEL =1;
    public static final int MINIMAL_FILE_LEVEL =2;

    private static final long DEFAULT_HASH_SIZE = 100 * 1024;
    private String name;
    private String fullpath;
    private String directoryAt;
    private String extension;
    private String source;
    private long fileSize;
    private boolean hidden;
    private byte[] hash;
    //private Calendar dtCreated;
    private Calendar dtModified;

    public SingleFileResult(String source, File file) {
        this.name = file.getName();
        this.extension = getExtension(this.name);
        this.source = source;
        this.fullpath = file.getPath();
        this.hidden = file.isHidden();
        this.directoryAt = file.getParent();
        this.fileSize = file.length();
        this.hash = getHash(file);        
        this.dtModified = Calendar.getInstance();
        this.dtModified.setTimeInMillis(file.lastModified());
    }

    private static volatile  MessageDigest digest =null;
    private static MessageDigest getDigest()
    {
        try
        {
        if (digest==null)
             digest = MessageDigest.getInstance("MD5");
        }
        catch (NoSuchAlgorithmException noEx) {
            
        }
        return digest;
    }

    private byte[] getHash(File file) {
        InputStream input = null;
        try {
            input = new FileInputStream(file);
            int readSize = (int) ( (DEFAULT_HASH_SIZE>file.length())? file.length() : DEFAULT_HASH_SIZE);
            byte[] buff = new byte[readSize];
            input.read(buff, 0, readSize);
            return getDigest().digest(buff);
        } catch (FileNotFoundException foEx) {

        } catch (IOException ioEx) {
            
        }
        return null;
    }

    public String getFileHash(int level)
    {
        StringWriter sw = new StringWriter();
        switch (level) {
            case FULL_FILE_LEVEL:
                sw.append(getMD5HashString());
            case NORMAL_FILE_LEVEL:
                sw.append(Long.toString(this.getFileSize()));
            case MINIMAL_FILE_LEVEL:
                sw.append(getName());
        }
        return sw.toString();
    }
    public String getMD5HashString()
    {
        if (getHash()!=null)
            return HexUtil.getHex(getHash());
        else
        {
            return "";
        }
    }

    private static String getExtension(String filename) {
        if ((filename != null) && (filename.contains("."))) {
            return filename.substring(filename.lastIndexOf("."));
        } else {
            return "";
        }
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @return the fullpath
     */
    public String getFullpath() {
        return fullpath;
    }

    /**
     * @return the extension
     */
    public String getExtension() {
        return extension;
    }

    /**
     * @return the source
     */
    public String getSource() {
        return source;
    }

    /**
     * @return the fileSize
     */
    public long getFileSize() {
        return fileSize;
    }

    /**
     * @return the hash
     */
    public byte[] getHash() {
        return hash;
    }
//
//    /**
//     * @return the dtCreated
//     */
//    public Calendar getDtCreated() {
//        return dtCreated;
//    }

    /**
     * @return the dtModified
     */
    public Calendar getDtModified() {
        return dtModified;
    }

    /**
     * @return the directoryAt
     */
    public String getDirectoryAt() {
        return directoryAt;
    }
}
